#include <iostream>
using namespace std;

template <int ObjectSize, int NumofObjects = 20>
class MemPool
{
private:
    // 空闲节点结构体
    struct FreeNode
    {
        FreeNode *pNext;
        // data：存储对象
        char data[ObjectSize];
    };

    // 内存块结构体
    struct MemBlock
    {
        // 内存块结构
        MemBlock *pNext;
        // 空闲块 --> 对象块
        FreeNode data[NumofObjects];
    };

    FreeNode *freeNodeHeader; // 空闲节点链表的头节点
    MemBlock *memBlockHeader; // 内存块的头节点

public:
    MemPool()
    {
        freeNodeHeader = NULL;
        memBlockHeader = NULL;
    }

    ~MemPool()
    {
        MemBlock *ptr;
        while (memBlockHeader)
        {
            ptr = memBlockHeader->pNext;
            delete memBlockHeader;
            memBlockHeader = ptr;
        }
    }

    // 分配空闲的结点。

    void *malloc()
    {
        // 无空闲节点，申请新内存块
        if (freeNodeHeader == NULL)
        {
            MemBlock *newBlock = new MemBlock;
            newBlock->pNext = NULL;
            // 当freeNodeHeader指向空的时候，表明第一个内存块已经用完了
            // 因此freeNodeHeader更改指向也没什么关系
            // 所以要申请新的内存块，让freeNodeHeader指向
            freeNodeHeader = &newBlock->data[0]; // 设置内存块的第一个节点为空闲节点链表的首节点
            // 将内存块的其它节点串起来
            for (int i = 1; i < NumofObjects; ++i)
            {
                newBlock->data[i - 1].pNext = &newBlock->data[i];
            }
            newBlock->data[NumofObjects - 1].pNext = NULL;

            // 首次申请内存块
            if (memBlockHeader == NULL)
            {
                memBlockHeader = newBlock;
            }
            else
            {
                // 将新内存块加入到内存块链表。
                newBlock->pNext = memBlockHeader;
                memBlockHeader = newBlock;
            }
        }
        // 返回空节点闲链表的第一个节点。
        void *freeNode = freeNodeHeader;
        freeNodeHeader = freeNodeHeader->pNext;
        return freeNode;
    }
    // 释放已经分配的结点。

    void free(void *p)
    {
        FreeNode *pNode = (FreeNode *)p;
        pNode->pNext = freeNodeHeader; // 将释放的节点插入空闲节点头部
        freeNodeHeader = pNode;
    }
};

class ActualClass
{
    static int count;
    int No;
    int c = 0;

public:
    ActualClass()
    {
        No = count;
        count++;
        cout << "ActualClass" << endl;
    }

    void print()
    {
        cout << this << ": ";
        cout << "the " << No << "th object" << endl;
    }

    void *operator new(size_t size);
    void operator delete(void *p);
};

// 定义内存池对象
MemPool<sizeof(ActualClass), 2> mp;

void *ActualClass::operator new(size_t size)
{
    return mp.malloc();
}

void ActualClass::operator delete(void *p)
{
    mp.free(p);
}

int ActualClass::count = 0;

int main()
{
    ActualClass *p1 = new ActualClass;
    p1->print();

    ActualClass *p2 = new ActualClass;
    p2->print();
    delete p1;

    p1 = new ActualClass;
    p1->print();

    ActualClass *p3 = new ActualClass;
    p3->print();

    delete p1;
    delete p2;
    delete p3;
}
